package org.example.gateway.filter;

import lombok.extern.slf4j.Slf4j;
import org.example.gateway.common.BackHttpStatus;
import org.example.user.service.UserFeignService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.cloud.gateway.filter.GatewayFilterChain;
import org.springframework.cloud.gateway.filter.GlobalFilter;
import org.springframework.core.Ordered;
import org.springframework.http.HttpCookie;
import org.springframework.http.HttpStatus;
import org.springframework.http.server.reactive.ServerHttpRequest;
import org.springframework.http.server.reactive.ServerHttpResponse;
import org.springframework.stereotype.Component;
import org.springframework.web.server.ServerWebExchange;
import reactor.core.publisher.Mono;

import java.util.HashSet;
import java.util.List;
import java.util.Set;

/**
 * Description: 统一认证（登录时验证⽤用户名密码是否合法，合法调⽤用⽤用户微服务⽣生成token，写⼊入cookie，并且携带邮
 * 箱地址重定向到欢迎⻚页⾯面
 * Author: e
 * CreateDate: 2021-05-31
 */
@Slf4j
@Component
public class AutoGlobalFiter implements GlobalFilter, Ordered {

    @Autowired
    private UserFeignService userFeignService;


    //放行的uri
    private static final Set<String> permitThroughPaths = new HashSet<>();


    static {
        permitThroughPaths.add("/api/user/register");
        permitThroughPaths.add("/api/user/login");
        permitThroughPaths.add("/api/code/create");
        permitThroughPaths.add("/api/code/isRegister");
    }

    @Override
    public Mono<Void> filter(ServerWebExchange exchange, GatewayFilterChain chain) {
        ServerHttpRequest request = exchange.getRequest();
        ServerHttpResponse response = exchange.getResponse();
        //获取路径
        String path = request.getURI().getPath();

        for (String permitThroughPath : permitThroughPaths) {
            if (path.startsWith(permitThroughPath)) {
                log.info("开放" + permitThroughPath + "，放行");
                return chain.filter(exchange);
            }
        }
        //当路径不在放行列表时
        // 2.1 获取Cookie
        List<HttpCookie> httpCookies = request.getCookies().get("token");
        if (httpCookies != null) {
            //携带token 时，判断当前token 是否存存在
            String email = userFeignService.info(httpCookies.get(0).getValue());
            if (email != null) {
                return chain.filter(exchange);
            }
        }
        //当用户不存在时
        //不放行 状态码
        return response.writeWith(Mono.just(BackHttpStatus.wrap(response, HttpStatus.UNAUTHORIZED)));
    }

    @Override
    public int getOrder() {
        return 0;
    }
}
